package com.training1.core.common.utils.pay.bohai.support;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Security;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.util.Enumeration;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;

import com.training1.core.common.utils.pay.bohai.BoHaiConfig;
import com.training1.core.common.utils.pay.bohai.BoHaiUtil;

public class PacKeyManager {
    protected static Logger log = BoHaiUtil.log;
    private String keystoreType = BoHaiConfig.keystoreType;
    private String keystoreFile = BoHaiConfig.keystoreFile;
    private String keystorePassword = BoHaiConfig.keystorePassword;
    private String keyAlias = BoHaiConfig.keyAlias;
    private String keyPassword = BoHaiConfig.keyPassword;
    private String serverCertAlias = BoHaiConfig.serverCertAlias;

    private KeyStore keyStore = null;

    
    public PacKeyManager(String keystoreFile) {
    	this.keystoreFile = keystoreFile;
    }

    public PacKeyManager() {
    }
    
    public String getKeystoreType() {
        return keystoreType;
    }

    public void setKeystoreType(String keystoreType) {
        this.keystoreType = keystoreType;
    }

    public String getKeystoreFile() {
        return keystoreFile;
    }

    public void setKeystoreFile(String keystoreFile) {
        this.keystoreFile = keystoreFile;
    }

    public String getKeystorePassword() {
        return keystorePassword;
    }

    public void setKeystorePassword(String keystorePassword) {
        this.keystorePassword = keystorePassword;
    }

    public String getKeyAlias() {
        return keyAlias;
    }

    public void setKeyAlias(String keyAlias) {
        this.keyAlias = keyAlias;
    }

    public String getKeyPassword() {
        return keyPassword;
    }

    public void setKeyPassword(String keyPassword) {
        this.keyPassword = keyPassword;
    }

    public PrivateKey getPrivateKey() {
        PrivateKey key = null;
        if (keyStore == null) {
        	try{
        		loadKeyStore();
        	}catch(FileNotFoundException e){
        		log.error("未找到渤海银行KEY文件");
        	}
        }

        try {
            key = (PrivateKey) keyStore.getKey(keyAlias,
                    keyPassword.toCharArray());
        } catch (UnrecoverableKeyException e) {
            log.error("Error get private key !", e);
        } catch (KeyStoreException e) {
            log.error("Error get private key !", e);
        } catch (NoSuchAlgorithmException e) {
            log.error("Error get private key !", e);
        }

        return key;
    }

    public Certificate getCertificate() {
        Certificate cert = null;
        try {
//            cert = keyStore.getCertificate(this.serverCertAlias);
            cert = keyStore.getCertificateChain(this.keyAlias)[0];
//            Certificate[] certificateChain2 = keyStore.getCertificateChain(this.serverCertAlias);
        } catch (KeyStoreException e) {
            log.error("Error get certificate key !", e);
        }
        return cert;
    }

    private void loadKeyStore() throws FileNotFoundException {
        InputStream inputStream = null;

        Security.addProvider(new BouncyCastleProvider());

        try {
            File fileOfCa = new File(keystoreFile);
            if (fileOfCa.exists()) {
                inputStream = new FileInputStream(fileOfCa);
            }
        } catch (FileNotFoundException fnfe) {
            log.error("Error load keystore!", fnfe);
        }

        try {
            inputStream = new FileInputStream(getKeystoreFile());
        } catch (FileNotFoundException e1) {
            log.error("Error in loadKeyStore File Not Found",e1);
        }

        if (inputStream == null) {
            log.error("Error in loadKeyStore File Not Found");
            throw new FileNotFoundException("渤海KEY未找到");
        } else {
            char[] pass = keystorePassword.toCharArray();

            try {
                keyStore = KeyStore.getInstance(keystoreType);
                keyStore.load(inputStream, pass);
            } catch (Exception e) {
                log.error("Error in PayGateSignVerify Load the Keystore ", e);
            }
        }
    }

    public String getServerCertAlias() {
        return serverCertAlias;
    }

    public void setServerCertAlias(String serverCertAlias) {
        this.serverCertAlias = serverCertAlias;
    }

    public static void main(String[] args) {
        try {
            String pfxFile = "/insttest.pfx";
            String jksFile = "/cbhbpac.jks";

            String alias = "key4pac";

            String pfxPwd = "111111";
            String jksPwd = "111111";
            String inputKeyPwd = "111111";
            String outputKeyPwd = "111111";

            char[] nPassword = null;

            KeyStore inputKeyStore = KeyStore.getInstance("PKCS12");
            FileInputStream fis = new FileInputStream(pfxFile);

            if (null != pfxPwd && !"".equals(pfxPwd)) {
                nPassword = pfxPwd.toCharArray();
            }
            inputKeyStore.load(fis, nPassword);

            fis.close();
            fis = null;

            KeyStore outputKeyStore = KeyStore.getInstance("JKS");
            outputKeyStore.load(null, jksPwd.toCharArray());

            Enumeration<String> enums = inputKeyStore.aliases();

            String keyAlias = enums.nextElement();
            System.out.println("Key alias:"+keyAlias);

            Key key = inputKeyStore.getKey(keyAlias, inputKeyPwd.toCharArray());
            Certificate[] certChain = inputKeyStore
                    .getCertificateChain(keyAlias);
            outputKeyStore.setKeyEntry(alias, key, outputKeyPwd.toCharArray(),
                    certChain);

            FileOutputStream fos = new FileOutputStream(jksFile);

            if (null != jksPwd && !"".equals(jksPwd)) {
                nPassword = jksPwd.toCharArray();
            }
            outputKeyStore.store(fos, nPassword);

            fos.close();
            fos = null;
        } catch (Throwable t) {
            t.printStackTrace();
        }

    }

}
